
namespace Mysoft.Dbf.Writers
{
    public class ArrayWriter : IWriter
    {
        byte _startFrom;
        byte _end;
        string _namingVariableName;
        IWriter _itemWriter;
        public ArrayWriter(string namingVariableName, byte startFrom, byte end, IWriter itemWriter)
        {
            _startFrom = startFrom;
            _end = end;
            _namingVariableName = namingVariableName;
            _itemWriter = itemWriter;
        }
        #region IFieldWriter Members

        public void WriteHeader(System.IO.Stream toStream, int offsetInRecord, NamingParameters namingParameters)
        {
            int currentOffsetInRecord = offsetInRecord;
            if (!namingParameters.ContainsKey(_namingVariableName))
                namingParameters.Add(_namingVariableName, "0");
            for (int i = _startFrom; i <= _end; i++)
            {
                namingParameters[_namingVariableName] = i.ToString();
                _itemWriter.WriteHeader(toStream, currentOffsetInRecord, namingParameters);
                currentOffsetInRecord += _itemWriter.FieldTotalLength;
            }
        }

        public void WriteValue(object value, System.IO.StreamWriter streamWriter)
        {
            int writtenItems = _startFrom;
            if (value != null)
            {
                foreach (object currentValue in ((System.Collections.IEnumerable)value))
                {
                    _itemWriter.WriteValue(currentValue, streamWriter);
                    writtenItems++;
                    if (writtenItems > _end) // make sure we don't write more then _end values - even if the target property contains more values
                        break;
                }
            }

            for (int i= writtenItems; i<= _end; i++) //complete the array with null values, in case the target property has fewer elemets 
            {
                _itemWriter.WriteValue(null, streamWriter);
            }
        }

        public short FieldTotalLength
        {
            get
            {
                return (short)(ArrayLength * _itemWriter.FieldTotalLength);
            }
        }

        private byte ArrayLength
        {
            get { return (byte)(_end - _startFrom + 1); }
        }

        public byte FieldCount
        {
            get { return (byte)(ArrayLength * _itemWriter.FieldCount); }
        }

        #endregion
    }
}
